package com.cn.xiaonuo.tcrfinance.tcrgnete.service.impl;

import cn.com.soole.gnete.payment.GneteSettleClient;
import cn.com.soole.gnete.payment.enums.GetCertTypeEnum;
import cn.com.soole.gnete.payment.request.merchant.QueryBalanceRequest;
import cn.com.soole.gnete.payment.response.merchant.QueryBalanceResponse;
import cn.com.soole.gnete.payment.util.Security;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cn.xiaonuo.common.constant.SmsConstant;
import com.cn.xiaonuo.common.constant.Status;
import com.cn.xiaonuo.common.entity.BusinessMessage;
import com.cn.xiaonuo.common.tools.RestTemplateUtil;
import com.cn.xiaonuo.common.utils.ExportExcelUtils;
import com.cn.xiaonuo.common.utils.OrderNumGeneration;
import com.cn.xiaonuo.common.utils.TencentSmsUtils;
import com.cn.xiaonuo.common.utils.payutils.GnetePayUtil;
import com.cn.xiaonuo.common.vo.ExcelData;
import com.cn.xiaonuo.tcrfinance.tcrgnete.constant.LedgerConstant;
import com.cn.xiaonuo.tcrfinance.tcrgnete.param.*;
import com.cn.xiaonuo.tcrfinance.tcrgnete.entiey.PvShopWallet;
import com.cn.xiaonuo.tcrfinance.tcrgnete.entiey.WalletRecord;
import com.cn.xiaonuo.tcrfinance.tcrgnete.entiey.WithdrawApply;
import com.cn.xiaonuo.tcrfinance.tcrgnete.mapper.PvShopWalletMapper;
import com.cn.xiaonuo.tcrfinance.tcrgnete.mapper.WalletRecordMapper;
import com.cn.xiaonuo.tcrfinance.tcrgnete.mapper.WithdrawApplyMapper;
import com.cn.xiaonuo.tcrfinance.tcrgnete.req.TimingUpdate;
import com.cn.xiaonuo.tcrfinance.tcrgnete.rsp.ThirdBalanceRsp;
import com.cn.xiaonuo.tcrfinance.tcrgnete.rsp.WithdrawRsp;
import com.cn.xiaonuo.tcrfinance.tcrgnete.rsp.WithdrawalStatusRsp;
import com.cn.xiaonuo.tcrfinance.tcrgnete.service.GnetePayService;
import com.github.qcloudsms.SmsSingleSenderResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @BelongsProject: slb-reports-java
 * @Author: likui
 * @CreateTime: 2022-11-03  15:18
 * @Description: 聚合支付
 */
@Slf4j
@Service
public class GnetePayServiceImpl implements GnetePayService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private PvShopWalletMapper pvShopWalletMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private WalletRecordMapper walletRecordMapper;
    @Autowired
    private WithdrawApplyMapper withdrawApplyMapper;
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private Environment environment;

    @Override
    public BusinessMessage accountBalance(String PSno) {
        BusinessMessage message = new BusinessMessage();
        try {
            LambdaQueryWrapper<PvShopWallet> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PvShopWallet::getDeleted, 0);
            queryWrapper.eq(PvShopWallet::getStatus, 1);
            queryWrapper.eq(PvShopWallet::getAccountType, 1);
            PvShopWallet pvShopWallet = pvShopWalletMapper.selectOne(queryWrapper);
            QueryBalanceRequest queryBalanceRequest = new QueryBalanceRequest();
            queryBalanceRequest.setType("RECV");
            queryBalanceRequest.setPsNo(PSno);
            String privateKeyByPfx = Security.getPrivateKeyByPfx(GnetePayUtil.PRIVATE_KEY, GnetePayUtil.PRIVATE_KEY_PASS, GetCertTypeEnum.BASE64);

            String pubKeyByPfx = Security.getPubKeyByPfx(GnetePayUtil.PUBULIC_KEY, GetCertTypeEnum.BASE64);
            GneteSettleClient gneteSettleClient = new GneteSettleClient(GnetePayUtil.APP_ID, pvShopWallet.getMerchantId(), privateKeyByPfx, pubKeyByPfx, GnetePayUtil.GNETE_URL);
            QueryBalanceResponse queryBalanceResponse = gneteSettleClient.queryBalance(queryBalanceRequest);
            message.setData(queryBalanceResponse);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
            message.setSuccess(true);
        } catch (Exception e) {
            message.setMessage(Status.fail);
            message.setCode(Status.failCode);
            message.setSuccess(false);
            log.error("结算余额查询失败，原因{}", e.getMessage());
        }

        return message;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage withdrawal(WithdrawalParam param) {
        BusinessMessage message = new BusinessMessage();
        if (ObjectUtils.isEmpty(param.getCode()) || ObjectUtils.isEmpty(param.getPhone())) {
            message.setMessage("参数不完整!");
            message.setCode(Status.failCode);
            message.setSuccess(false);
            return message;
        }
        //短信验证码
        String code = LedgerConstant.WITHDRAWAL_CODE + param.getPhone();
        //锁（防止重复请求）
        String withdrawalLock = LedgerConstant.WITHDRAWAL_LOCK + param.getPhone();
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(withdrawalLock, 1, 15, TimeUnit.MINUTES);
        boolean skip = false;
        try {
            if (!lock) {
                message.setMessage("正在购买，请勿重复提交");
                log.info("正在购买，请勿重复提交{}", code);
                return message;
            }
            String num = stringRedisTemplate.opsForValue().get(code);
            if (ObjectUtils.isEmpty(num)) {
                message.setCode(Status.failCode);
                message.setMessage("验证码已过期,稍后重新发送验证码");
                message.setSuccess(false);
                skip = true;
                return message;
            }
            if (!num.equals(param.getCode())) {
                message.setMessage("验证码有误!");
                message.setCode(Status.failCode);
                message.setSuccess(false);
                skip = true;
                return message;
            }
            if (ObjectUtils.isEmpty(param.getReceiverMerchantNo())) {
                message.setMessage("该商家暂未完成进件!");
                message.setCode(Status.failCode);
                message.setSuccess(false);
                return message;
            }
            if (ObjectUtils.isEmpty(param.getAmount()) || param.getAmount() <= 0) {
                message.setMessage("请正确输入金额!");
                message.setCode(Status.failCode);
                message.setSuccess(false);
                return message;
            }
            LambdaQueryWrapper<PvShopWallet> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PvShopWallet::getStatus, 1);
            wrapper.eq(PvShopWallet::getDeleted, 0);
            wrapper.eq(PvShopWallet::getPsNo, param.getReceiverMerchantNo());
            PvShopWallet pvShopWallet = pvShopWalletMapper.selectOne(wrapper);
            if (ObjectUtils.isNotEmpty(pvShopWallet)) {
                String url = environment.getProperty("gwq.gwqUrl");
                String method = environment.getProperty("gwq.withdraw");
                String token = environment.getProperty("gwq.token");
                String json = JSON.toJSONString(param);
                log.info("乡村振兴分账提现调用开始：参数{}", json);
                Map post = restTemplateUtil.post(url, method, json, token);
                Object data = post.get("data");
                if (ObjectUtils.isNotEmpty(data)) {
                    Map map = (Map) data;
                    WithdrawRsp withdrawRsp = new WithdrawRsp();
                    withdrawRsp.setAmount(Convert.toLong(map.get("amount")));
                    withdrawRsp.setNo(Convert.toStr(map.get("no")));
                    withdrawRsp.setRemark(Convert.toStr(map.get("remark")));
                    withdrawRsp.setStatus(Convert.toInt(map.get("status")));
                    withdrawRsp.setPsNo(pvShopWallet.getPsNo());
                    //增加提现记录
                    this.addWithdrawApply(withdrawRsp.getNo(), withdrawRsp, param);
                    //增加资金流水记录
                    this.withdrawalAddWalletRecord(withdrawRsp.getNo(), pvShopWallet, withdrawRsp, withdrawRsp.getRemark());
                    //余额提现，受理中将余额扣减，冻结增加，待提现成功将冻结扣减
                    pvShopWalletMapper.updateAmount(pvShopWallet.getId(), withdrawRsp.getAmount());
                    message.setMessage("提现申请成功");
                    message.setCode(Status.successCode);
                    message.setSuccess(true);
                }else {
                    message.setMessage(Status.fail);
                    message.setCode(Status.failCode);
                    message.setSuccess(false);
                }
            }
        } catch (Exception e) {
            message.setMessage(Status.fail);
            message.setCode(Status.failCode);
            message.setSuccess(false);
            log.error("提现失败，原因:{}", e.getMessage());
            e.printStackTrace();

        } finally {
            if (!skip) {
                redisTemplate.delete(code);
            }
            redisTemplate.delete(withdrawalLock);
        }

        return message;
    }

    //增加资金流水记录
    public void withdrawalAddWalletRecord(String coReqSn, PvShopWallet pvShopWallet, WithdrawRsp withdrawRsp, String coRemark) {
        //增加资金流水记录
        WalletRecord walletRecord = new WalletRecord();
        walletRecord.setUserId(pvShopWallet.getUserId());
        walletRecord.setWalletId(pvShopWallet.getId());
        walletRecord.setBeforeBalance(pvShopWallet.getAvailableAmount());
        walletRecord.setAmount(withdrawRsp.getAmount());
        walletRecord.setAfterBalance(pvShopWallet.getAvailableAmount() - withdrawRsp.getAmount()<=0 ? 0 : pvShopWallet.getAvailableAmount() - withdrawRsp.getAmount());
        walletRecord.setFrozenBeforeAmount(pvShopWallet.getFrozenAmount());
        walletRecord.setFrozenAmount(withdrawRsp.getAmount());
        walletRecord.setFrozenAfterAmount(pvShopWallet.getFrozenAmount() + withdrawRsp.getAmount());
        walletRecord.setTradeType(1);
        walletRecord.setTotalAmount(walletRecord.getAfterBalance() + walletRecord.getFrozenAfterAmount());
        walletRecord.setMerchantOrderNo(coReqSn);
        walletRecord.setRemark(coRemark);
        walletRecordMapper.insert(walletRecord);
    }

    //增加提现记录
    public void addWithdrawApply(String coReqSn, WithdrawRsp withdrawRsp, WithdrawalParam param) {
        WithdrawApply withdrawApply = new WithdrawApply();
        withdrawApply.setMerchantOrderNo(coReqSn);
        withdrawApply.setAmount(withdrawRsp.getAmount());
        withdrawApply.setUserId(param.getUserId());
        withdrawApply.setOperatorId(param.getOperatorId());
        withdrawApply.setOperatorName(param.getOperatorName());
        withdrawApply.setCoRemark(withdrawRsp.getRemark());
        withdrawApply.setStatus(withdrawRsp.getStatus());
        if (param.getReceiverType().equals(0)) {
            withdrawApply.setAccountType(2);
        } else if (param.getReceiverType().equals(1)) {
            withdrawApply.setAccountType(1);
        }
        withdrawApply.setPsNo(withdrawRsp.getPsNo());
        withdrawApplyMapper.insert(withdrawApply);
    }

    @Override
    public BusinessMessage verificationCode(String phone) {
        BusinessMessage message = new BusinessMessage();
        String lockCode = LedgerConstant.REPEAT_SENDING_LOCK + phone;
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(lockCode, 1, 15, TimeUnit.MINUTES);
        try {
            if (!lock) {
                message.setMessage("正在发送，请勿重复提交");
                log.info("正在发送，请勿重复提交{}",phone);
                return message;
            }
                String code = LedgerConstant.WITHDRAWAL_CODE + phone;
                String o = stringRedisTemplate.opsForValue().get(code);
                String codeNew = OrderNumGeneration.generateNum();
                //判断验证码是否过期
                if (ObjectUtil.isNotEmpty(o)) {
                    message.setMessage("请勿重复发送验证码");
                    message.setSuccess(false);
                    message.setCode(Status.failCode);
                    return message;
                } else {
                    stringRedisTemplate.opsForValue().set(code, codeNew, 15, TimeUnit.MINUTES);
                    String[] msg = {"资金提现验证码发送成功，验证码为" + codeNew + ",该验证码15分钟内有效"};
                    SmsSingleSenderResult result1 = TencentSmsUtils.smsSingleSender(
                            SmsConstant.appid,
                            SmsConstant.appkey,
                            "86", phone, SmsConstant.CHECK_DATA_INFO, msg,
                            "全球乡村振兴", "", "");

                    message.setMessage(Status.success);
                    message.setCode(Status.successCode);
                    message.setSuccess(true);
                }
            } catch(Exception e){
                message.setMessage(e.getMessage());
                message.setSuccess(false);
                message.setCode(Status.failCode);
                log.error("短信验证码发送失败，原因:{}", e.getMessage());
            }finally {
            redisTemplate.delete(lockCode);
        }
            return message;
        }

        @Override
        public BusinessMessage fundInformation (FundInformationParam param){
            BusinessMessage message = new BusinessMessage();
            if (ObjectUtils.isEmpty(param.getPsNo())) {
                message.setMessage("该商家暂未进件!");
                message.setCode(Status.failCode);
                message.setSuccess(false);
                return message;
            }
            LambdaQueryWrapper<PvShopWallet> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PvShopWallet::getDeleted, 0);
            wrapper.eq(PvShopWallet::getStatus, 1);
            wrapper.eq(PvShopWallet::getPsNo, param.getPsNo());
            PvShopWallet pvShopWallet = pvShopWalletMapper.selectOne(wrapper);
            pvShopWallet.setTotalAmount(pvShopWallet.getAvailableAmount() + pvShopWallet.getFrozenAmount());
            message.setData(pvShopWallet);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
            message.setSuccess(true);
            return message;
        }

        @Override
        public BusinessMessage capitalFlow (CapitalFlowParam param){
            BusinessMessage message = new BusinessMessage();
            if (ObjectUtils.isEmpty(param.getWalletId())) {
                message.setMessage("该商家暂未进件!");
                message.setCode(Status.failCode);
                message.setSuccess(false);
                return message;
            }
            LambdaQueryWrapper<WalletRecord> wrapper = new LambdaQueryWrapper<>();
            if (ObjectUtils.isNotEmpty(param.getCreateBeginTime()) || ObjectUtils.isNotEmpty(param.getCreateEndTime())) {
                wrapper.between(WalletRecord::getCreatedTime, param.getCreateBeginTime(), param.getCreateEndTime());
            }
            if (ObjectUtils.isNotEmpty(param.getTradeType())) {
                wrapper.eq(WalletRecord::getTradeType, param.getTradeType());
            }
            wrapper.eq(WalletRecord::getWalletId, param.getWalletId());
            wrapper.orderByDesc(WalletRecord::getCreatedTime);
            Page<WalletRecord> walletRecordPage = walletRecordMapper.selectPage(new Page<>(param.getCurrentPage(), param.getPageSize()), wrapper);
            message.setData(walletRecordPage);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
            message.setSuccess(true);
            return message;
        }

        @Override
        public BusinessMessage withdrawalRecord (CapitalFlowParam param){
            BusinessMessage message = new BusinessMessage();
            if (ObjectUtils.isEmpty(param.getPsNo())) {
                message.setMessage("该商家暂未进件!");
                message.setCode(Status.failCode);
                message.setSuccess(false);
                return message;
            }
            Map<String, Object> map = new HashMap<>();
            LambdaQueryWrapper<WithdrawApply> wrapper = this.withdrawalRecordWapper(param);
            Page<WithdrawApply> withdrawApplyPage = withdrawApplyMapper.selectPage(new Page<>(param.getCurrentPage(), param.getPageSize()), wrapper);
            Map<String, Object> sumAmount = withdrawApplyMapper.sumAmount(param);
            map.put("pageInfo", withdrawApplyPage);
            map.put("amount", sumAmount.get("amount"));
            message.setData(map);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
            message.setSuccess(true);
            return message;
        }

        public LambdaQueryWrapper<WithdrawApply> withdrawalRecordWapper (CapitalFlowParam param){
            LambdaQueryWrapper<WithdrawApply> wrapper = new LambdaQueryWrapper<>();
            if (ObjectUtils.isNotEmpty(param.getCreateBeginTime()) || ObjectUtils.isNotEmpty(param.getCreateEndTime())) {
                wrapper.between(WithdrawApply::getCreateTime, param.getCreateBeginTime(), param.getCreateEndTime());
            }
            if (ObjectUtils.isNotEmpty(param.getStatus())) {
                wrapper.eq(WithdrawApply::getStatus, param.getStatus());
            }
            if (ObjectUtils.isNotEmpty(param.getMerchantOrderNo())) {
                wrapper.eq(WithdrawApply::getMerchantOrderNo, param.getMerchantOrderNo());
            }
            wrapper.eq(WithdrawApply::getPsNo, param.getPsNo());
            wrapper.eq(WithdrawApply::getDeleted, 0);
            wrapper.orderByDesc(WithdrawApply::getCreateTime);
            return wrapper;
        }


        @Override
        @Transactional(rollbackFor = Exception.class)
        public BusinessMessage timingUpdate () throws Exception {
            log.info("提现记录状态同步计划任务执行开始!");
            BusinessMessage message = new BusinessMessage();
            String serialNumber = null;
            int count = 0;
            try {
//            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
                LambdaQueryWrapper<WithdrawApply> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(WithdrawApply::getStatus, 0);
                wrapper.eq(WithdrawApply::getDeleted, 0);
                List<WithdrawApply> withdrawApplies = withdrawApplyMapper.selectList(wrapper);
                if (withdrawApplies.size() > 0) {
                    for (WithdrawApply withdrawApplie : withdrawApplies) {
                        LambdaQueryWrapper<PvShopWallet> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(PvShopWallet::getPsNo, withdrawApplie.getPsNo());
                        PvShopWallet pvShopWallet = pvShopWalletMapper.selectOne(queryWrapper);
                        Long frozenAmount = pvShopWallet.getFrozenAmount();
                        Long availableAmount = pvShopWallet.getAvailableAmount();
                        serialNumber = withdrawApplie.getMerchantOrderNo();
                        String url = environment.getProperty("gwq.gwqUrl");
                        String method = environment.getProperty("gwq.queryWithdrawByNo");
                        String token = environment.getProperty("gwq.token");
                        TimingUpdate timingUpdate = new TimingUpdate();
                        timingUpdate.setNo(withdrawApplie.getMerchantOrderNo());
                        String json = JSON.toJSONString(timingUpdate);
                        log.info("乡村振兴分账提现调用开始：参数{}", json);
                        String queryWithdrawByNo = restTemplateUtil.postString(url, method, json, token);
                        log.info("乡村振兴分账提现调用结果返回为：{}", queryWithdrawByNo);
                        if (ObjectUtils.isNotEmpty(queryWithdrawByNo)) {
                            JSONObject data = JSONObject.parseObject(queryWithdrawByNo);
                            JSONObject jsonObject = data.getJSONObject("data");
                            WithdrawalStatusRsp withdrawalStatusRsp = jsonObject.toJavaObject(WithdrawalStatusRsp.class);

                            WithdrawApply withdrawApply = new WithdrawApply();
                            withdrawApply.setId(withdrawApplie.getId());
                            withdrawApply.setStatus(withdrawalStatusRsp.getStatus());
                            withdrawApply.setCoRemark(withdrawalStatusRsp.getRemark());
                            withdrawApply.setUpdateTime(new Date());
                            withdrawApplyMapper.updateById(withdrawApply);
                            //如果提现成功
                            if (withdrawalStatusRsp.getStatus().equals(1)) {
                                //提现完成后将冻结金额提到可用中(扣减冻结)
                                pvShopWallet.setFrozenAmount(pvShopWallet.getFrozenAmount() - withdrawApplie.getAmount());
                                pvShopWalletMapper.updateById(pvShopWallet);
                                //提现成功增加资金流水
                                this.addWalletRecord(serialNumber, pvShopWallet, withdrawApplie, 2, withdrawalStatusRsp.getRemark(), frozenAmount, null);
                                count += 1;
                            } else if (withdrawalStatusRsp.getStatus().equals(2)) {
                                pvShopWallet.setFrozenAmount(pvShopWallet.getFrozenAmount() - withdrawApplie.getAmount());
                                pvShopWallet.setAvailableAmount(pvShopWallet.getAvailableAmount() + withdrawApplie.getAmount());
                                pvShopWalletMapper.updateById(pvShopWallet);
                                //提现失败
                                this.addWalletRecord(serialNumber, pvShopWallet, withdrawApplie, 3, withdrawalStatusRsp.getRemark(), frozenAmount, availableAmount);
                            }
                        }
                    }
                }
                message.setMessage(Status.success);
                message.setCode(Status.successCode);
                message.setSuccess(true);
            } catch (Exception e) {
                log.error("流水单号为：[{}]，数据状态同步失败，原因：{}", serialNumber, e.getMessage());
                message.setMessage(e.getMessage());
                message.setCode(Status.failCode);
                message.setSuccess(false);
            }
            log.info("本次任务同步成功，{}条数据", count);
            return message;
        }

        @Override
        public BusinessMessage withdrawalRecordExcel (HttpServletResponse response, CapitalFlowParam param){
            SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            LambdaQueryWrapper<WithdrawApply> wrapper = this.withdrawalRecordWapper(param);
            List<WithdrawApply> withdrawApplies = withdrawApplyMapper.selectList(wrapper);
            try {
                List<List<Object>> rows = new ArrayList();
                ExcelData data = new ExcelData();
                data.setName("提现记录导出");//sheet表名称
                //表头
                List<String> titles = new ArrayList();
                titles.add("申请时间");
                titles.add("提现金额(元)");
                titles.add("提现状态");
                titles.add("商户订单号");
                data.setTitles(titles);
                for (WithdrawApply withdrawApply : withdrawApplies) {
                    String createTime = ymdhms.format(withdrawApply.getCreateTime());
                    List<Object> row1 = new ArrayList();
                    row1.add(createTime);
                    row1.add(withdrawApply.getAmount().doubleValue() / 100);
                    if (withdrawApply.getStatus().equals(0)) {
                        row1.add("处理中");
                    } else if (withdrawApply.getStatus().equals(1)) {
                        row1.add("成功");
                    } else if (withdrawApply.getStatus().equals(2)) {
                        row1.add("失败");
                    }
                    row1.add(withdrawApply.getMerchantOrderNo());
                    rows.add(row1);
                }
                data.setRows(rows);
                ExportExcelUtils.exportExcel(response, "提现记录导出.xlsx", data);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public BusinessMessage queryThirdBalance (ThirdBalanceParam param){
            BusinessMessage message = new BusinessMessage();
            if (ObjectUtils.isEmpty(param.getReceiverType())) {
                message.setMessage("分账接收方类型不能为空!");
                message.setCode(Status.failCode);
                message.setSuccess(false);
                return message;
            }
            if (param.getReceiverType().equals(0)) {
                if (ObjectUtils.isEmpty(param.getReceiverMerchantNo())) {
                    message.setMessage("进件编号不能为空!");
                    message.setCode(Status.failCode);
                    message.setSuccess(false);
                    return message;
                }
            }
            String url = environment.getProperty("gwq.gwqUrl");
            String method = environment.getProperty("gwq.thirdBalance");
            String token = environment.getProperty("gwq.token");
            String json = JSON.toJSONString(param);
            log.info("乡村振兴余额查询调用开始：参数{}", json);
            Map respose = restTemplateUtil.post(url, method, json, token);
            Object data = respose.get("data");
            if (ObjectUtils.isEmpty(data)) {
                log.error("提现余额查询失败，原因{}", respose.get("message"));
                message.setMessage(Status.fail);
                message.setCode(Status.failCode);
                message.setSuccess(true);
                return message;
            }
            Map map = (Map) data;
            ThirdBalanceRsp thirdBalanceRsp = new ThirdBalanceRsp();
            thirdBalanceRsp.setBalance(Convert.toLong(map.get("balance")));
            thirdBalanceRsp.setFrozenBalance(Convert.toLong(map.get("frozenBalance")));
            thirdBalanceRsp.setAvailableBalance(Convert.toLong(map.get("availableBalance")));
            thirdBalanceRsp.setReceiverMerchantNo(Convert.toStr(map.get("receiverMerchantNo")));
            message.setData(thirdBalanceRsp);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
            message.setSuccess(true);
            return message;
        }

        public void addWalletRecord (String serialNumber, PvShopWallet pvShopWallet, WithdrawApply
        withdrawApplie, Integer tradeType, String coRemark, Long frozenAmount, Long availableAmount){
            String orderNum = OrderNumGeneration.generateOrderId();
            QueryWrapper<WalletRecord> recordQueryWrapper = new QueryWrapper<>();
            recordQueryWrapper.eq("merchant_order_no", serialNumber);
            recordQueryWrapper.eq("trade_type", 1);
            WalletRecord walletRecord = walletRecordMapper.selectOne(recordQueryWrapper);
            walletRecord.setSerialNumber(orderNum);
            if (tradeType.equals(2)) {
                //提现成功可用余额不变，冻结金额扣除
                walletRecord.setBeforeBalance(pvShopWallet.getAvailableAmount());
                walletRecord.setAmount(0L);
                walletRecord.setAfterBalance(pvShopWallet.getAvailableAmount());
            } else if (tradeType.equals(3)) {
                //提现失败退回冻结余额增加可用余额
                walletRecord.setBeforeBalance(availableAmount);
                walletRecord.setAmount(withdrawApplie.getAmount());
                walletRecord.setAfterBalance(pvShopWallet.getAvailableAmount());
            }
            walletRecord.setFrozenBeforeAmount(frozenAmount);
            walletRecord.setFrozenAmount(withdrawApplie.getAmount());
            walletRecord.setFrozenAfterAmount(pvShopWallet.getFrozenAmount());
            walletRecord.setTradeType(tradeType);
            walletRecord.setTotalAmount(walletRecord.getAfterBalance() + walletRecord.getFrozenAfterAmount());
            walletRecord.setCreatedTime(new Date());
            walletRecord.setUpdatedTime(new Date());
            walletRecord.setRemark(coRemark);
            walletRecordMapper.insert(walletRecord);
        }

    }
